home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / corelib / ncbistr.c < prev    next >
Text File  |  1996-07-05  |  12KB  |  470 lines

  1. /*   ncbistr.c
  2. * ===========================================================================
  3. *
  4. *                            PUBLIC DOMAIN NOTICE                          
  5. *               National Center for Biotechnology Information
  6. *                                                                          
  7. *  This software/database is a "United States Government Work" under the   
  8. *  terms of the United States Copyright Act.  It was written as part of    
  9. *  the author's official duties as a United States Government employee and 
  10. *  thus cannot be copyrighted.  This software/database is freely available 
  11. *  to the public for use. The National Library of Medicine and the U.S.    
  12. *  Government have not placed any restriction on its use or reproduction.  
  13. *                                                                          
  14. *  Although all reasonable efforts have been taken to ensure the accuracy  
  15. *  and reliability of the software and data, the NLM and the U.S.          
  16. *  Government do not and cannot warrant the performance or results that    
  17. *  may be obtained by using this software or data. The NLM and the U.S.    
  18. *  Government disclaim all warranties, express or implied, including       
  19. *  warranties of performance, merchantability or fitness for any particular
  20. *  purpose.                                                                
  21. *                                                                          
  22. *  Please cite the author in any work or product based on this material.   
  23. *
  24. * ===========================================================================
  25. *
  26. * File Name:  ncbistr.c
  27. *
  28. * Author:  Gish, Kans, Ostell, Schuler
  29. *
  30. * Version Creation Date:   3/4/91
  31. *
  32. * $Revision: 2.4 $
  33. *
  34. * File Description: 
  35. *       portable string routines
  36. *
  37. * Modifications:  
  38. * --------------------------------------------------------------------------
  39. * Date     Name        Description of modification
  40. * -------  ----------  -----------------------------------------------------
  41. * 3/4/91   Kans        Stricter typecasting for GNU C and C++.
  42. * 09-19-91 Schuler     Changed all types expressing sizes to size_t.
  43. * 09-19-91 Schuler     Changed return type for compare functions to int.
  44. * 09-19-91 Schuler     Changed all functions to _cdecl calling convention.
  45. * 09-19-91 Schuler     Where possible, NCBI functions call the actual ANSI
  46. *                       functions after checking for NULL pointers.
  47. * 09-19-91 Schuler     Debug-class error posted on any NULL argument.
  48. * 09-19-91 Schuler     StringSave() calls MemGet() instead of MemNew().
  49. * 09-19-91 Schuler     StringSave(NULL) returns NULL.
  50. * 10-17-91 Schuler     Removed ErrPost() calls on NULL arguments.
  51. * 10-17-91 Schuler     Added Nlm_StringCnt(),Nlm_StringStr(),Nlm_StringTok()
  52. * 11-18-91 Schuler     Added more ANSI-style functions
  53. * 04-15-93 Schuler     Changed _cdecl to LIBCALL
  54. * 05-27-93 Schuler     Added const qualifiers to match ANSI cognates
  55. *
  56. * ==========================================================================
  57. */
  58.  
  59. #include <ncbi.h>
  60. #include <ncbiwin.h>
  61.  
  62. /* ClearDestString clears the destination string if the source is NULL. */
  63. static Nlm_CharPtr NEAR Nlm_ClearDestString (Nlm_CharPtr to, Nlm_sizeT max)
  64. {
  65.   if (to != NULL && max > 0) {
  66.     Nlm_MemSet (to, 0, max);
  67.     *to = '\0';
  68.   }
  69.   return to;
  70. }
  71.  
  72. Nlm_sizeT LIBCALL  Nlm_StringLen (const char *str)
  73. {
  74.     return str ? StrLen (str) : 0;
  75. }
  76.  
  77. Nlm_CharPtr LIBCALL  Nlm_StringCpy (char FAR *to, const char FAR *from)
  78. {
  79.     return (to && from) ? StrCpy (to, from) : Nlm_ClearDestString (to, 1);
  80. }
  81.  
  82. Nlm_CharPtr LIBCALL  Nlm_StringNCpy (char FAR *to, const char FAR *from, Nlm_sizeT max)
  83. {
  84.     return (to && from) ? StrNCpy (to, from, max) : Nlm_ClearDestString (to, max);
  85. }
  86.  
  87. Nlm_CharPtr LIBCALL  Nlm_StringCat (char FAR *to, const char FAR *from)
  88. {
  89.     return (to && from) ? StrCat (to, from) : to;
  90. }
  91.  
  92. Nlm_CharPtr LIBCALL  Nlm_StringNCat (char FAR *to, const char FAR *from, Nlm_sizeT max)
  93. {       
  94.     return (to && from) ? StrNCat (to, from, max) : to;
  95. }
  96.  
  97. int LIBCALL  Nlm_StringCmp (const char FAR *a, const char FAR *b)
  98. {
  99. #ifdef DCLAP
  100.     /* return a sensible result of one str is NULL, e.g. NULL < anystring */
  101.     if (a && b) return StrCmp(a,b);
  102.     else if (a) return 1;
  103.     else if (b) return -1;
  104.     else return 0;
  105. #else
  106.     return  (a && b) ? StrCmp (a, b) : 0;
  107. #endif
  108. }
  109.  
  110. int LIBCALL  Nlm_StringNCmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
  111. {
  112. #ifdef DCLAP
  113.     if (a && b) return StrNCmp (a, b, max);
  114.     else if (a) return 1;
  115.     else if (b) return -1;
  116.     else return 0;
  117. #else
  118.     return (a && b) ? StrNCmp (a, b, max) : 0;
  119. #endif
  120. }
  121.  
  122. int LIBCALL  Nlm_StringICmp (const char FAR *a, const char FAR *b)
  123. {
  124. #ifdef DCLAP
  125.     if (a && b) return Nlm_StrICmp (a, b);
  126.     else if (a) return 1;
  127.     else if (b) return -1;
  128.     else return 0;
  129. #else
  130.     return (a && b) ? Nlm_StrICmp (a, b) : 0;
  131. #endif
  132. }
  133.  
  134. int LIBCALL  Nlm_StringNICmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
  135. {
  136. #ifdef DCLAP
  137.     if (a && b) return Nlm_StrNICmp (a, b, max);
  138.     else if (a) return 1;
  139.     else if (b) return -1;
  140.     else return 0;
  141. #else
  142.     return (a && b) ? Nlm_StrNICmp (a, b, max) : 0;
  143. #endif
  144. }
  145.  
  146. Nlm_CharPtr LIBCALL  Nlm_StringChr (const char FAR *str, int chr)
  147. {
  148.     return str ? Nlm_StrChr(str,chr) : NULL;
  149. }
  150.  
  151. Nlm_CharPtr LIBCALL  Nlm_StringRChr (const char FAR *str, int chr)
  152. {
  153.     return str ? Nlm_StrRChr(str,chr) : NULL;
  154. }
  155.  
  156. Nlm_sizeT LIBCALL  Nlm_StringSpn (const char FAR *a, const char FAR *b)
  157. {
  158.     return (a && b) ? Nlm_StrSpn (a, b) : 0;
  159. }
  160.  
  161. Nlm_sizeT LIBCALL  Nlm_StringCSpn (const char FAR *a, const char FAR *b)
  162. {
  163.     return (a && b) ? Nlm_StrCSpn (a, b) : 0;
  164. }
  165.  
  166. Nlm_CharPtr LIBCALL  Nlm_StringPBrk (const char FAR *a, const char FAR *b)
  167. {
  168.     return (a && b) ? Nlm_StrPBrk (a, b) : NULL;
  169. }
  170.  
  171. Nlm_CharPtr LIBCALL  Nlm_StringStr (const char FAR *str1, const char FAR *str2)
  172. {
  173.     return (str1 && str2) ? Nlm_StrStr(str1,str2) : NULL;
  174. }
  175.  
  176. Nlm_CharPtr LIBCALL  Nlm_StringTok (char FAR *str1, const char FAR *str2)
  177. {
  178.     return str2 ? Nlm_StrTok(str1,str2) : NULL;
  179. }
  180.  
  181. Nlm_CharPtr LIBCALL  Nlm_StringMove (char FAR *to, const char FAR *from)
  182. {
  183.     return (to && from) ? Nlm_StrMove (to, from) : to;
  184. }
  185.  
  186. Nlm_CharPtr LIBCALL  Nlm_StringSave (const char FAR *from)
  187. {
  188.     return from ? Nlm_StrSave (from) : NULL;
  189. }
  190.  
  191. Nlm_CharPtr LIBCALL  Nlm_StringSaveNoNull (const char FAR *from)
  192. {
  193.     if (from == NULL) return NULL;
  194.     if (*from == '\0') return NULL;
  195.     return Nlm_StrSave (from);
  196. }
  197.  
  198. Nlm_sizeT LIBCALL  Nlm_StringCnt (const char FAR *str, const char FAR *list)
  199. {
  200.     return (str && list) ? Nlm_StrCnt(str,list) : 0;
  201. }
  202.  
  203. char * LIBCALL Nlm_StringUpper (char *string)
  204. {
  205.     return (string == NULL) ? NULL : Nlm_StrUpper(string);
  206. }
  207.  
  208. char * LIBCALL Nlm_StringLower (char *string)
  209. {
  210.     return (string == NULL) ? NULL : Nlm_StrLower(string);
  211. }
  212.  
  213.  
  214.  
  215. int LIBCALL  Nlm_StrICmp (const char FAR *a, const char FAR *b)
  216. {
  217.     int diff, done;
  218.  
  219.     if (a == b)   return 0;
  220.  
  221.     done = 0;
  222.     while (! done)
  223.     {
  224.         diff = TO_UPPER(*a) - TO_UPPER(*b);
  225.         if (diff)
  226.             return (Nlm_Int2) diff;
  227.         if (*a == '\0')
  228.             done = 1;
  229.         else
  230.         {
  231.             a++; b++;
  232.         }
  233.     }
  234.     return 0;
  235. }
  236.  
  237. int LIBCALL  Nlm_StrNICmp (const char FAR *a, const char FAR *b, Nlm_sizeT max)
  238. {
  239.     int diff, done;
  240.     
  241.     if (a == b)   return 0;
  242.  
  243.     done = 0;
  244.     while (! done)
  245.     {
  246.         diff = TO_UPPER(*a) - TO_UPPER(*b);
  247.         if (diff)
  248.             return (Nlm_Int2) diff;
  249.         if (*a == '\0')
  250.             done = 1;
  251.         else
  252.         {
  253.             a++; b++; max--;
  254.             if (! max)
  255.                 done = 1;
  256.         }
  257.     }
  258.     return 0;
  259. }
  260.  
  261. Nlm_CharPtr LIBCALL  Nlm_StrSave (const char FAR *from)
  262. {
  263.     Nlm_sizeT len;
  264.     Nlm_CharPtr to;
  265.  
  266.     len = Nlm_StringLen(from);
  267.     if ((to = (Nlm_CharPtr) Nlm_MemGet(len +1, FALSE)) != NULL) {
  268.         Nlm_MemCpy (to, from, len +1);
  269.     }
  270.     return to;
  271. }
  272.  
  273. Nlm_CharPtr LIBCALL  Nlm_StrMove (char FAR *to, const char FAR *from)
  274. {
  275.     while (*from != '\0')
  276.     {
  277.         *to = *from;
  278.         to++; from++;
  279.     }
  280.     *to = '\0';
  281.     return to;
  282. }
  283.  
  284. Nlm_sizeT LIBCALL  Nlm_StrCnt (const char FAR *s, const char FAR *list)
  285. {
  286.     Nlm_sizeT    cmap[1<<CHAR_BIT];
  287.     Nlm_Byte    c;
  288.     Nlm_sizeT    u, cnt;
  289.     const Nlm_Byte *bs = (const Nlm_Byte*)s;
  290.     const Nlm_Byte *blist = (const Nlm_Byte*)list;
  291.  
  292.     if (s == NULL || list == NULL)
  293.         return 0;
  294.  
  295.     for (u = 0; u < DIM(cmap); ++u)
  296.         cmap[u] = 0;
  297.     while (*blist != '\0')
  298.         ++cmap[*blist++];
  299.  
  300.     blist = (Nlm_BytePtr)cmap;
  301.  
  302.     cnt = 0;
  303.     while ((c = *bs++) != '\0')
  304.         cnt += blist[c];
  305.  
  306.     return cnt;
  307. }
  308.  
  309.  
  310. #ifndef COMP_MSC
  311. char * LIBCALL Nlm_StrUpper (char *string)
  312. {
  313.     register char *p = string;
  314.     ASSERT(string != NULL);
  315.     while (*p)
  316.     {
  317.         if (isalpha(*p))
  318.             *p = (char)toupper(*p);
  319.         ++p;
  320.     }
  321.     return string;
  322. }
  323. #endif
  324.  
  325. #ifndef COMP_MSC
  326. char * LIBCALL Nlm_StrLower (char *string)
  327. {
  328.     register char *p = string;
  329.     ASSERT(string != NULL);
  330.     while (*p)
  331.     {
  332.         if (isalpha(*p))
  333.             *p = (char)tolower(*p);
  334.         ++p;
  335.     }
  336.     return string;
  337. }
  338. #endif
  339.  
  340.  
  341. /*  -------------------- MeshStringICmp() --------------------------------
  342.  *  MeshStringICmp compares strings where / takes precedence to space.
  343.  */
  344.  
  345. Nlm_Int2 LIBCALL Nlm_MeshStringICmp (const char FAR *str1, const char FAR *str2)
  346. {
  347.     Nlm_Char  ch1, ch2;
  348.  
  349.     if (str1 == NULL)
  350.     {
  351.         if (str2 == NULL)
  352.             return (Nlm_Int2)0;
  353.         else
  354.             return (Nlm_Int2)1;
  355.     }
  356.     else if (str2 == NULL)
  357.         return (Nlm_Int2)-1;
  358.  
  359.     while ((*str1 >= ' ') && (*str2 >= ' ') && (TO_LOWER(*str1) == TO_LOWER(*str2)))
  360.     {
  361.         str1++; str2++;
  362.     }
  363.  
  364.     ch1 = *str1;
  365.     ch2 = *str2;
  366.     if ((ch1 < ' ') && (ch2 < ' '))
  367.         return (Nlm_Int2)0;
  368.     else if (ch1 < ' ')
  369.         return (Nlm_Int2)-1;
  370.     else if (ch2 < ' ')
  371.         return (Nlm_Int2)1;
  372.  
  373.     if (ch1 == '/')
  374.       ch1 = '\31';
  375.     if (ch2 == '/')
  376.       ch2 = '\31';
  377.  
  378.     if (TO_LOWER (ch1) > TO_LOWER (ch2))
  379.       return (Nlm_Int2)1;
  380.     else if (TO_LOWER (ch1) < TO_LOWER (ch2))
  381.       return (Nlm_Int2)(-1);
  382.     else
  383.       return (Nlm_Int2)0;
  384. }
  385.  
  386.  
  387. /*****************************************************************************
  388. *
  389. *   LabelCopy (to, from, buflen)
  390. *       Copies the string "from" into "to" for up to "buflen" chars
  391. *       if "from" is longer than buflen, makes the last character '>'
  392. *       always puts one '\0' to terminate the string in to
  393. *       to MUST be one character longer than buflen to leave room for the
  394. *           last '\0' if from = buflen.
  395. *       returns number of characters transferred to "to"
  396. *
  397. *****************************************************************************/
  398. Nlm_Int2 LIBCALL Nlm_LabelCopy (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen)
  399. {
  400.     Nlm_Int2 len;
  401.  
  402.     if ((to == NULL) || (from == NULL) || (buflen < 0)) return 0;
  403.     
  404.     if (buflen == 0)         /* this is a sign of multiple writes */
  405.     {
  406.         *(to-1) = '>';
  407.         return 0;
  408.     }
  409.     
  410.     len = buflen;
  411.  
  412.     while ((*from != '\0') && (buflen))
  413.     {
  414.         *to = *from;
  415.         from++; to++; buflen--;
  416.     }
  417.  
  418.     if (*from != '\0')
  419.     {
  420.         *(to - 1) = '>';
  421.     }
  422.  
  423.     *to = '\0';      /* buffer is bufferlen+1 */
  424.     return (len - buflen);
  425. }
  426.  
  427. void LIBCALL Nlm_LabelCopyNext(Nlm_CharPtr PNTR to, Nlm_CharPtr from, Nlm_Int2 PNTR buflen)
  428. {
  429.     Nlm_Int2 diff;
  430.  
  431.     diff = Nlm_LabelCopy(*to, from, *buflen);
  432.     *buflen -= diff; *to += diff;
  433.     
  434. }
  435.  
  436. /*****************************************************************************
  437. *
  438. *   LabelCopyExtra (to, from, buflen, prefix, suffix)
  439. *       Copies the string "from" into "to" for up to "buflen" chars
  440. *       if all together are longer than buflen, makes the last character '>'
  441. *       always puts one '\0' to terminate the string in to
  442. *       to MUST be one character longer than buflen to leave room for the
  443. *           last '\0' if from = buflen.
  444. *       returns number of characters transferred to "to"
  445. *
  446. *       if not NULL, puts prefix before from and suffix after from
  447. *           both contained within buflen
  448. *  
  449. *
  450. *****************************************************************************/
  451. Nlm_Int2 LIBCALL Nlm_LabelCopyExtra (Nlm_CharPtr to, Nlm_CharPtr from, Nlm_Int2 buflen, Nlm_CharPtr prefix, Nlm_CharPtr suffix)
  452. {
  453.     Nlm_Int2 len, diff;
  454.  
  455.     if ((to == NULL) || (buflen < 1) || (from == NULL)) return 0;
  456.  
  457.     len = buflen;
  458.     diff = Nlm_LabelCopy(to, prefix, buflen);
  459.     buflen -= diff; to += diff;
  460.  
  461.     diff = Nlm_LabelCopy(to, from, buflen);
  462.     buflen -= diff; to += diff;
  463.  
  464.     diff = Nlm_LabelCopy(to, suffix, buflen);
  465.     buflen -= diff;
  466.  
  467.     return (len-buflen);
  468. }
  469.  
  470.